package socketmvc.core.processor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import socketmvc.core.config.SocketMvcConfig;
import socketmvc.core.context.IContext;
import socketmvc.core.packets.ErrorPacket;
import socketmvc.core.packets.SocketClosePacket;
import socketmvc.core.packets.WsHandshakePacket;
import socketmvc.core.packets.basic.IPacket;
import socketmvc.core.packets.basic.JsonBasicPacket;
import socketmvc.core.processor.annotation.SocketCommand;
import socketmvc.core.processor.annotation.SocketControl;

@SocketControl("/@")
public class SockInbuiltProcessor {

    private static final Logger logger = LoggerFactory.getLogger(SockInbuiltProcessor.class);

    /**
     * 心跳处理
     * @param packet 消息包
     * @param context tcp上下文
     */
    @SocketCommand("beat-heart")
    public IPacket beatHeart(JsonBasicPacket packet, IContext context){
        // 给客户端回复心跳包
        return packet;
    }

    /**
     * websocket 握手阶段会回调当前函数
     * @param packet 消息包
     */
    @SocketCommand("ws-handshake")
    public void wsHandshake(IPacket packet){
        if (packet instanceof WsHandshakePacket wsPacket){
            if (wsPacket.shakingHands()){
                // 注意正在握手阶段不能使用context发送数据，否则会导致握手失败
                // 默认情况下，什么都不做会顺利握手
                // 如果想阻止握手，可以抛出一个运行时异常
                // 例如 ： throw new IllegalArgumentException("握手参数有问题");
            }
        }
    }

    /**
     * websocket 握手完成后回调当前函数
     * @param packet 消息包
     * @param context tcp上下文
     */
    @SocketCommand("ws-handshake-after")
    public void wsHandshakeAfter(IPacket packet, IContext context){
        if (packet instanceof WsHandshakePacket wsPacket){
            // 已经握手成功
            context.send(wsPacket);
        }
    }


    /**
     * 客户端主动触发关闭socket时回调当前函数
     * @param packet 消息包
     * @param context tcp上下文
     */
    @SocketCommand("socket-close")
    public void socketOnClose(SocketClosePacket packet, IContext context){
        // 客户端主动触发关闭socket时回调当前函数
    }


    /**
     * 客户端发生一些需要服务端知道的错误时的回调函数
     * @param packet 消息包
     * @param context tcp上下文
     */
    @SocketCommand("error-response")
    public void errorResponse(ErrorPacket packet, IContext context){
        // 客户端主动触发关闭socket时回调当前函数
        String host = null;
        SocketMvcConfig.IpConfig clientConnInfo = context.getClientConnInfo();
        if (clientConnInfo != null){
            host = clientConnInfo.getHost();
        }else {
            SocketMvcConfig.IpConfig serverConnInfo = context.getServerConnInfo();
            if (serverConnInfo != null){
                host = serverConnInfo.getHost();
            }
        }
        String msg = packet.toBean(String.class);
        logger.info("对端上报了异常信息 ===> host: {} , msg: {}", host ,msg);

    }

}
